#ifndef __Campo_H__
#define __Campo_H__

#include <iostream>

using namespace std;

class Campo;

ostream &operator<<(ostream &os,const Campo &campo);
istream &operator>>(istream &is,Campo &campo);

class Campo
{

private:
	
	typedef enum
	{
		VOID,
		INT,
		LONG,
		FLOAT,
		DOUBLE,
		CHAR
	}Tipo;

public:

	/**
	* Se crea un campo vacio.
	*/
	Campo();

	/**
	* Se crea un campo de tipo char con el valor pasado y la longitud pasada.
	* Si la longitud es cero, entonce se creara con la longitud del valor
	* pasado.
	* @param valor Valor a ser asignado al campo a crear.
	* @param longitud Cantidad de caracteres que tendr� el campo a crear. Si
	* es cero se toma la longitud del valor pasado.
	*/
	Campo(const char *valor,const int longitud=0);

	/**
	* Constructor de copia.
	*/
	Campo (const Campo &campo);
	
	Campo(istream &is);

	/**
	* Se elimina a this.
	*/
	~Campo();

	/**
	* Se asigna el campo pasado.
	* @param campo Campo a ser asignado.
	* @return Una referencia a this.
	*/
	Campo &operator=(const Campo &campo);

	/**
	* Se asigna el valor pasado al campo. En caso de no ser un campo de tipo 
	* CHAR se lo convierte a dicho tipo con una longitud igual a la del valor 
	* pasado. En caso de ser un campo de tipo CHAR se respetar� la longitud de
	* this al hacer la asignaci�n.
	* @param valor Valor a ser seteado.
	*/
	Campo &operator=(const char *valor);

	/**
	* Se asigna el valor pasado al campo. Se convierte el campo en caso de
	* corresponder.
	* @param valor Valor a ser seteado.
	*/
	Campo &operator=(const int &valor);

	/**
	* Se asigna el valor pasado al campo. Se convierte el campo en caso de
	* corresponder.
	* @param valor Valor a ser seteado.
	*/
	Campo &operator=(const long &valor);

	/**
	* Se asigna el valor pasado al campo. Se convierte el campo en caso de
	* corresponder.
	* @param valor Valor a ser seteado.
	*/
	Campo &operator=(const float &valor);

	/**
	* Se asigna el valor pasado al campo. Se convierte el campo en caso de
	* corresponder.
	* @param valor Valor a ser seteado.
	*/
	Campo &operator=(const double &valor);

	/**
	* Operador igual.
	* @param valor Valor con el cual se comparara.
	* @return true si son iguales, sino false.
	*/
	bool operator==(const Campo &campo) const;

	/**
	* Operador menor.
	* @param valor Valor con el cual se comparara.
	* @return true si this es menor que valor, sino false.
	*/
	bool operator<(const Campo &campo) const;

	/**
	* Obtiene los datos de this de un istream.
	* @param is istream de donde se obtendrean los datos de this.
	*/
	void read(istream &is);

	/**
	* Escribe los datos de this a un ostream.
	* @param os ostream en el cual se escribir�n los datos.
	*/
	void write(ostream &) const;

	
	void* getValor(){return valor;}

protected:
	
	Tipo tipo;
	int longitud;
	void *valor;

	friend ostream &operator<<(ostream &os,const Campo &campo);
	friend istream &operator>>(istream &is,Campo &campo);


};

#endif
